/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Common;

import DAO.AccountDAO;
import DAO.NotificationDAO;
import DAO.PriceHistoryDAO;
import DAO.TrackedProductDAO;
import hibernate.entity.Account;
import hibernate.entity.Notification;
import hibernate.entity.TrackedProduct;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;


import java.math.BigInteger;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Random;
import java.util.ResourceBundle;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.List;
import org.apache.lucene.util.IOUtils;

/**
 *
 * @author NamDH
 */
public class CommonUtil {

    //input an string and return numbers (if String has numbers :)))
    private static ResourceBundle rbBundle = ResourceBundle.getBundle("db");

    public static double getNumberfromString(String inputString) {
        double result = 0;
        Pattern p = Pattern.compile("[\\d\\.]+");
        Matcher m = p.matcher(inputString);
        while (m.find()) {
            result = Double.parseDouble(m.group());
        }
        return result;
    }

    public static String getWebContentbyURL(String weburl) {
        String result = "";
        try {
            URL url = new URL(weburl);
            URLConnection con = url.openConnection();
            InputStream in = con.getInputStream();

            String encoding = con.getContentEncoding();
            encoding = encoding == null ? "UTF-8" : encoding;
            result = org.apache.commons.io.IOUtils.toString(in, encoding);
            return result;
        } catch (UnknownHostException ex) {
            ex.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }
    //get tag content - return String

    public static String getTagContent(String webcontent, String keyword) {
        String result = "";
        try {
            int keyindex = webcontent.indexOf(keyword) + keyword.length();

            int firstindex = 0;
            int lastindex = 0;
            int spanindex = webcontent.substring(keyindex).indexOf("</span>") + 6;
            int iflag = keyindex;
            //turong hop itemtitle
            if (keyword.equals("id=\"itemTitle\"") && !webcontent.contains("Broadleaf Demo")) {
                iflag = spanindex + keyindex;
            }
            for (int i = iflag; i < webcontent.length(); i++) {
                String sflag = webcontent.substring(i, i + 1);
                if (sflag.equals(">")) {
                    firstindex = i;
                    break;
                }
            }


            for (int i = firstindex; i < webcontent.length(); i++) {
                String flag = webcontent.substring(i, i + 1);
                if (flag.equals("<")) {
                    lastindex = i;
                    break;
                }
            }
            result = webcontent.substring(firstindex + 1, lastindex);
        } catch (StringIndexOutOfBoundsException ex) {
            ex.printStackTrace();
        }

        return result;
    }

    public static String getImagesrc(String webcontent, String keyword) {
        String result = "";
        int firstindex = webcontent.indexOf(keyword);
        String substring = webcontent.substring(firstindex);
        int srcindex = substring.indexOf("src=\"");
        int lastindex = 0;
        for (int i = srcindex + 5; i < substring.length(); i++) {
            String flag = substring.substring(i, i + 1);
            if (flag.equals("\"")) {
                lastindex = i;
                break;
            }
        }
        result = substring.substring(srcindex + 5, lastindex);
        return result;
    }

    public static String md5(String input) {

        String md5 = null;

        if (null == input) {
            return null;
        }

        try {

            //Create MessageDigest object for MD5
            MessageDigest digest = MessageDigest.getInstance("MD5");

            //Update input string in message digest
            digest.update(input.getBytes(), 0, input.length());

            //Converts message digest value in base 16 (hex)
            md5 = new BigInteger(1, digest.digest()).toString(16);

        } catch (NoSuchAlgorithmException e) {

            e.printStackTrace();
        }
        return md5;
    }

    public static String makeNewPassword() {
        Random random = new Random();
        String randomPass = "";
        for (int i = 0; i < 8; i++) {
            int randomNum = random.nextInt(74) + 48; // get random in 48-122: from 0-z
            randomPass += (char) randomNum;
        }
        return randomPass;
    }

    public static boolean sendEmail(String email, String password) {
        String host = "smtp.gmail.com";
        String username = rbBundle.getString("gmailAccount"); // Put here only Gmail username not full email id
        String myPassword = rbBundle.getString("passGmail"); // Put here Gmail password
        try {
            Properties props = new Properties();
            props.put("mail.smtps.auth", "true");
            props.put("mail.from", rbBundle.getString("gmail")); // put here from full gmail email id
            Session session = Session.getInstance(props, null);
            Transport t = session.getTransport("smtps");
            t.connect(host, username, myPassword);
            MimeMessage msg = new MimeMessage(session);
            msg.setFrom();
            msg.setRecipients(Message.RecipientType.TO, email); // put here receiver email id
            msg.setSubject(rbBundle.getString("contentEmail1"));
            msg.setSentDate(new Date());
            msg.setText(rbBundle.getString("contentEmail2") + password + rbBundle.getString("contentEmail3"));
            t.sendMessage(msg, msg.getAllRecipients());
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public static boolean sendEmail(String email, String content, String subject) {
        String host = "smtp.gmail.com";
        String username = rbBundle.getString("gmailAccount"); // Put here only Gmail username not full email id
        String myPassword = rbBundle.getString("passGmail"); // Put here Gmail password
        try {
            Properties props = new Properties();
            props.put("mail.smtps.auth", "true");
            props.put("mail.from", rbBundle.getString("gmail")); // put here from full gmail email id
            Session session = Session.getInstance(props, null);
            Transport t = session.getTransport("smtps");
            t.connect(host, username, myPassword);
            MimeMessage msg = new MimeMessage(session);
//            MailMessage


            msg.setFrom();
            msg.setRecipients(Message.RecipientType.TO, email); // put here receiver email id
            msg.setSubject(subject);
            msg.setSentDate(new Date());
            msg.setText(content);
            t.sendMessage(msg, msg.getAllRecipients());
            return true;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return false;
    }

    public static String getCurrentTime() {
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        Date date = new Date();
        return dateFormat.format(date);
    }

    public static boolean writeProperty(String value, String propName, String path) {
        FileInputStream fi = null;
        FileOutputStream fo = null;
        try {
            fi = new FileInputStream(path);
            Properties properties = new Properties();
            properties.load(fi);
            fo = new FileOutputStream(path);
            properties.setProperty(propName, value);
            properties.store(fo, null);
            return true;
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
            return false;
        } catch (Exception ex) {
            return false;
        } finally {
            try {
                fi.close();
            } catch (IOException ex) {
                Logger.getLogger(CommonUtil.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public static String readProperties(String keyName) {
        return rbBundle.getString(keyName);
    }

    public static void updateInfo() {
        System.out.println("Running this code every " + Global.timeInterval + " second...");
        AccountDAO accountDAO = new AccountDAO();

        TrackedProductDAO tpDAO = new TrackedProductDAO();
        PriceHistoryDAO phDAO = new PriceHistoryDAO();


        NotificationDAO noDao = new NotificationDAO();
        List<Account> accounts = accountDAO.getAllAccount();
        for (final Account account : accounts) {
            List<Integer> productIdflag = new ArrayList<Integer>();
            List<TrackedProduct> trackedProducts = tpDAO.getTrackedProductbyAccountId(account.getAccountID());
            for (TrackedProduct trackedProduct : trackedProducts) {
                String webcontent = CommonUtil.getWebContentbyURL(trackedProduct.getProductLink());
                // String url = trackedProduct.getProductLink();
//                String keysearch = url.contains("ebay") ? Global.ebay_ProductPrice_KeySearch : Global.demoWeb_ProductPrice_KeySearch;
                if(!webcontent.equals("")){
                   String keysearch = Global.ebay_ProductPrice_KeySearch;
                double lastprice = phDAO.getLastPriceHistorybyTPID(trackedProduct.getTrackedProductId());
                double currentprice = CommonUtil.getNumberfromString(CommonUtil.getTagContent(webcontent, keysearch));
                if (lastprice != currentprice) {
                    phDAO.addNewPriceHistory(trackedProduct, currentprice);
                    if (currentprice <= trackedProduct.getDesiredPrice() && currentprice > 0) {
                        productIdflag.add(trackedProduct.getTrackedProductId());
                    }
                }  
                }

            }
            Notification notification = noDao.checkNotification(account.getAccountID(), 2);
            if (notification.isAccepted() && productIdflag.size() > 0) {
                String emailbody = "";
                final String subject = "[PRTS] - Desired price!";
                for (Integer i : productIdflag) {
                    TrackedProduct trackedproduct = tpDAO.getTrackedProductbyProduct_ID(i);
                    emailbody += trackedproduct.getProductName() + ": $" + phDAO.getLastPriceHistorybyTPID(trackedproduct.getTrackedProductId()) + "\n";
                }
                final String emailcontent = "Dear " + account.getUsername() + "\n"
                        + "Your product(s) have price equal or lower your desired price: \n" + emailbody
                        + rbBundle.getString("emailFooter");
                         sendEmail(account.getEmailAddress(), emailcontent, subject);
//                System.out.println("Main....: " + Thread.currentThread().getName());
//
//                Thread sendMailThread = new Thread() {
//
//                    public void run() {
//                        System.out.println("Seding mail....: " + Thread.currentThread().getName());
//
//                        System.out.println("Done Seding mail....");
//                    }
//                };
//                sendMailThread.run();
//                System.out.println("Do other checking....");
                //sendEmail(account.getEmailAddress(), emailcontent, subject);
            }

        }
//                List<TrackedProduct> trackedProducts = tpDAO.getAllProductForUpdatePrice();
//                for(TrackedProduct trackedproduct : trackedProducts){
//                     String webcontent = CommonUtil.getWebContentbyURL(trackedproduct.getProductLink());
//                    double lastprice = phDAO.getLastPriceHistorybyTPID(trackedproduct.getTrackedProductId());
//                    double currentprice = CommonUtil.getNumberfromString(CommonUtil.getTagContent(webcontent, Global.ebay_ProductPrice_KeySearch));
//                    if(lastprice!=currentprice){
//                        phDAO.addNewPriceHistory(trackedproduct, currentprice);
//                    }
//                }

    }

    public static void sendEmailWeekend() {
        AccountDAO accDao = new AccountDAO();
        PriceHistoryDAO phDAO = new PriceHistoryDAO();
        TrackedProductDAO tpDAO = new TrackedProductDAO();
        NotificationDAO noDao = new NotificationDAO();
        List<Account> accounts = accDao.getAllAccount();
        String subject = rbBundle.getString("weekendEmailSubject");
        for (Account account : accounts) {
            String emailbody = "";
            Notification notification = noDao.checkNotification(account.getAccountID(), 1);
            if (notification.isAccepted()) {
                List<TrackedProduct> trackedProducts = tpDAO.getTrackedProductbyAccount_Id(account.getAccountID());
                //kiem tra tracked product co moi gui mail
                if (trackedProducts.size() > 0) {
                    for (TrackedProduct trackedproduct : trackedProducts) {
                        emailbody += trackedproduct.getProductName() + ": $" + phDAO.getLastPriceHistorybyTPID(trackedproduct.getTrackedProductId()) + "\n\n";
                    }
                    //email content
                    String emailcontent = "Dear " + account.getUsername() + "\n\n"
                            + rbBundle.getString("weekendEmailHeader") + emailbody
                            + rbBundle.getString("emailFooter");
                    sendEmail(account.getEmailAddress(), emailcontent, subject);
                }
            }

        }

    }

    public static List getLastTenItem(List list) {
        List result = new ArrayList();
        for (int i = 1; i < 11; i++) {
            if (list.size() >= i) {
                result.add(list.get(list.size() - i));
            } else {
                break;
            }
        }
        return result;
    }

    public static boolean checkProductURL(String url) {
        if (!url.equals("") && url != null) {
            if (url.toLowerCase().contains(Global.ebayLink)
                    || url.toLowerCase().contains(Global.demoLink)) {
                return true;
            }
        }
        return false;
    }
}
